package tcp.server;

import bean.EqimInfo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import com.alibaba.fastjson.JSONObject;
import util.DBUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    DBUtil dbUtil = DBUtil.getInstance();

    /**
     * 收到客户端消息，自动触发
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


        ByteBuf buf = (ByteBuf) msg;
        /**readableBytes：获取缓冲区可读字节数,然后创建字节数组
         * 从而避免了像 java.nio.ByteBuffer 时，只能盲目的创建特定大小的字节数组，比如 1024
         * */
        byte[] reg = new byte[buf.readableBytes()];
        /**readBytes：将缓冲区字节数组复制到新建的 byte 数组中
         * 然后将字节数组转为字符串
         * */
        buf.readBytes(reg);
        String body = new String(reg, "UTF-8");
        System.out.println("收到消息:"+body);


        /**
         * 回复消息
         *
         * */
        String respMsg = getMsgFromDB(body);

        System.out.println("发送消息："+respMsg);



        ByteBuf respByteBuf = Unpooled.copiedBuffer(respMsg.getBytes("UTF-8"));
        ctx.write(respByteBuf);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        /**flush：将消息发送队列中的消息写入到 SocketChannel 中发送给对方，为了频繁的唤醒 Selector 进行消息发送
         * Netty 的 write 方法并不直接将消息写如 SocketChannel 中，调用 write 只是把待发送的消息放到发送缓存数组中，再通过调用 flush
         * 方法，将发送缓冲区的消息全部写入到 SocketChannel 中
         * */
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        /**当发生异常时，关闭 ChannelHandlerContext，释放和它相关联的句柄等资源 */
        dbUtil.clseRes();
        ctx.close();
    }


    /**
     * 从数据库获取返回信息
     * @return
     */
    private String getMsgFromDB(String username) throws Exception {

        //通过用户名查询用户已经获取信息的最大Id，没有就新建用户

        int maxId = getMaxIdByUsername(username);


        String sql = "select * from eqim_info where id > ?";
        List<Object> param = new ArrayList<>();
        param.add(maxId);

        ResultSet resultSet = dbUtil.query(sql,param);

        List<String> msgList = new ArrayList<>();

        while(resultSet.next()){
            EqimInfo info = new EqimInfo();
            info.setNetwork_Code(resultSet.getString("network_Code"));
            info.setNetwork_Cname(resultSet.getString("network_Cname"));
            info.setCata_ID(resultSet.getString("cata_ID"));
            info.setEvent_ID(resultSet.getString("event_ID"));
            info.setEq_Time(resultSet.getString("eq_Time"));
            info.setEq_Lat(resultSet.getString("eq_Lat"));
            info.setEq_Lon(resultSet.getString("eq_Lon"));
            info.setEq_Depth(resultSet.getString("eq_Depth"));
            info.setEq_M(resultSet.getString("eq_M"));
            info.setEq_Cname(resultSet.getString("eq_Cname"));

            msgList.add(info.toString());
        }
        dbUtil.clseRes();

        //获取信息最大id
        sql = "select max(id) from eqim_info";
        resultSet = dbUtil.query(sql,null);

        if (resultSet.next()){
            maxId = resultSet.getInt(1);
        }
        dbUtil.clseRes();


        //修改用户信息最大Id
        sql = "update user set max_msg = ? where name = ?";
        param.clear();
        param.add(maxId);
        param.add(username);
        dbUtil.update(sql,param);


        dbUtil.clseRes();

        if (msgList.size()==0){
            msgList.add("无最新消息");
        }

        return JSONObject.toJSONString(msgList);
    }

    /**
     * 获取用户已获取的信息最大id
     * @param username
     * @return
     * @throws SQLException
     */
    private int getMaxIdByUsername(String username) throws SQLException {

        int maxId = 0;



        //判断用户是否存在
        String sql = "select * from user where name = ?";

        List<Object> param = new ArrayList<>();
        param.add(username);
        ResultSet resultSet = dbUtil.query(sql, param);

        //不存在则新增用户
       if (!resultSet.next()){
            sql = "insert into user(name) value(?)";
            param.clear();
            param.add(username);
            dbUtil.update(sql,param);
       }
        dbUtil.clseRes();


       sql = "select max_msg from user where name = ?";
       param.clear();
       param.add(username);
       resultSet = dbUtil.query(sql,param);



       if (resultSet.next()){
           maxId = resultSet.getInt(1);
       }

       dbUtil.clseRes();

       return maxId;

    }





}
